/**
* @file system.c
* @brief system function
* @details system support
* @author huangbin
* @version V1.0.0
* @date 2025-04-20
* @copyright All documents are copyrighted by Shenzhen Xinlongwei Technology Co., LTD.
*            They may not be used for commercial purposes without permission
*/

#include "inc.h"

void SysTick_Handler(void)
{
}
void SoftwareDelayMs(uint32_t ms)
{
    volatile uint32_t i,j;
    
    if(ms < 1000)
    {
        WatchDogFeed();
        for(i = 0;i < ms;i++)
        {
            for(j = 0;j < 4500;j++);
        }
    }
    else
    {
        for(i = 0;i < ms;i++)
        {
            WatchDogFeed();
            for(j = 0;j < 4500;j++);
        }
    }
}
void HardFault_Handler(void)
{
#define WORD_LED_PORT   GPIOC
#define WORD_LED_PIN    GPIO_Pin_13

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    GPIO_InitStructure.GPIO_Pin = WORD_LED_PIN;		 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(WORD_LED_PORT, &GPIO_InitStructure);
    DebugPrintf("HardFault_Handler!\r\n");
    while(1)
    {
        volatile uint32_t i;
        WatchDogFeed();
        GPIO_ResetBits(WORD_LED_PORT, WORD_LED_PIN);   // Toggle LED
        for ( i = 0; i < 66666; ++i) __NOP();
        GPIO_SetBits(WORD_LED_PORT, WORD_LED_PIN);   // Toggle LED
        for ( i = 0; i < 66666; ++i) __NOP();
    }
}

void WatchDogInit(void)
{
#ifdef WATCHDOG_ENABLE	
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	IWDG_SetPrescaler(IWDG_Prescaler_128); //clock input = 40K,period = 3.2ms
	IWDG_SetReload(1000); //(0 -4095)3.2s
	IWDG_ReloadCounter(); 
	IWDG_Enable(); 	
	DebugPrintf("watchdog running!\r\n");
#endif	
}

void WatchDogFeed(void)
{
#ifdef WATCHDOG_ENABLE	
	IWDG_ReloadCounter();
//	DebugPrintf("watchdog Feed!\r\n");
#endif	
}

void RCC_ClkConfiguration(void)
{
    RCC_DeInit();

    RCC_HSEConfig(RCC_HSE_ON);
    while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

    RCC_PLLCmd(DISABLE);

    FLASH_SetLatency(FLASH_Latency_2);

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_27);

    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    RCC_PCLK1Config(RCC_HCLK_Div2);
    RCC_PCLK2Config(RCC_HCLK_Div1);

    RCC_LSICmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) __NOP();
    RCC_HSICmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) __NOP();
    
    SystemCoreClockUpdate();
}

uint16_t GetFlashCapacity(void)
{
    uint32_t c = *(uint32_t*)0x1FFFF7E0;
    DebugPrintf("Chip Flash size = %dKB\r\n",c & 0x0000FFFF);
    return c & 0x0000FFFF;
}

void GetChipId(uint32_t* c95_64,uint32_t* c63_32,uint32_t* c31_00)
{
    uint32_t c1 = *(uint32_t*)0x1FFFF7E0 + 0x08;
    uint32_t c2 = *(uint32_t*)0x1FFFF7E0 + 0x0C;
    uint32_t c3 = *(uint32_t*)0x1FFFF7E0 + 0x010;
    if(c95_64)
        *c95_64 = c3;
    if(c63_32)
        *c63_32 = c2;
    if(c31_00)
        *c31_00 = c1;
    DebugPrintf("Chip Id U_ID[95:64]=0x%08x,U_ID[63:32]=0x%08x,U_ID[31:0]= 0x%08x\r\n",c3,c2,c1);
}

//复用jtag功能，flash的spi共用
void JtagRemap(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
    //remap
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //PA13,PA14 for sw-dp,pa15,pb3,pb4 for io
}
//////////////////////////////File end/////////////////////////////////////

